#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include "Thread.hpp"
#include "Mutex.hpp"
#include "Cond.hpp"
#include "Task.hpp"
#include "Log.hpp"

namespace ThreadPool_Module
{
	using namespace ThreadModule;
	using namespace MutexModule;
	using namespace CondModule;
	using namespace LogModule;

	const int DefaultThreadNum = 5;

	template <class T>
	class ThreadPool
	{
	public:
		ThreadPool(int count = DefaultThreadNum) : _count(count), _isrunning(false), _waitnum(0)
		{
			_threads.reserve(_count);
			for (int i = 0; i < count; ++i)
			{
				_threads.emplace_back([this]()
									  { this->HandlerTask(); });
			}
		}

		// 启动所有工作线程
		void Start()
		{
			_isrunning = true;

			for (auto &t : _threads)
			{
				t.Start();
				LOG(LogLevel::INFO) << "线程 " << t.GetName() << " 已启动";
				sleep(1);
			}

			std::cout << "线程池已启动，工作线程数量：" << _count << std::endl;
			sleep(1);
		}

		void HandlerTask()
		{
			char name[64];
			pthread_getname_np(pthread_self(), name, sizeof(name));

			while (true)
			{
				T task;
				{
					MutexGuard guard(_mutex);
					LOG(LogLevel::INFO) << "线程 " << name << " 正在查看线程池及其任务队列状况";
					while (_taskqueue.empty() && _isrunning)
					{
						_waitnum++;
						_cond.Wait(_mutex);
						_waitnum--;
						LOG(LogLevel::INFO) << "线程 " << name << " 正在等待任务";
						sleep(1);
					}

					if (_taskqueue.empty() && !_isrunning)
					{
						break;
					}

					task = _taskqueue.front();
					_taskqueue.pop();
				}

				LOG(LogLevel::DEBUG) << "线程 " << name << " 开始执行任务";
				task(); // 执行取出的任务
				LOG(LogLevel::INFO) << "线程 " << name << " 完成任务";
				
				sleep(1);
			}
		}

		// 通知所有工作线程退出，唤醒等待的线程
		void Stop()
		{
			if (!_isrunning)
				return;

			MutexGuard guard(_mutex);
			_isrunning = false;
			_cond.Broadcast(); // 唤醒所有等待的线程
			LOG(LogLevel::INFO) << "线程池已停止，等待任务的线程数量: " << _waitnum;
			sleep(1);
		}

		// 阻塞当前进程，等待所有工作线程完成
		void Wait()
		{
			for (auto &t : _threads)
			{
				LOG(LogLevel::INFO) << "等待线程 " << t.GetName() << " 结束";
				t.Join();
			}
		}

		// 向任务队列添加任务
		void Enqueue(const T &task)
		{
			MutexGuard guard(_mutex);

			if (!_isrunning)
			{
				LOG(LogLevel::ERROR) << "线程池已停止，无法添加新任务";
				return;
			}

			_taskqueue.push(task);

			if (_waitnum > 0)
			{
				_cond.Signal();
				_waitnum--;
			}

			LOG(LogLevel::INFO) << "已添加任务到任务队列";
			sleep(1);
		}

		~ThreadPool() {}

	private:
		std::vector<Thread> _threads; // 线程池中的线程
		std::queue<T> _taskqueue;	  // 任务队列
		Mutex _mutex;
		Cond _cond; // 条件变量，用于线程的 “等待 / 唤醒”
		bool _isrunning;
		int _count;	  // 工作线程的数量
		int _waitnum; // 等待任务的线程数量
	};

}
